using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEngine;

namespace UnityEditorUI
{
    /// <summary>
    /// Drop-down selection field.
    /// </summary>
    public interface IDropdownBox : IWidget
    {
        /// <summary>
        /// Currently selected item.
        /// </summary>
        IPropertyBinding<object, IDropdownBox> SelectedItem { get; }

        /// <summary>
        /// List of items to display. Names are generated by calling ToString on each item.
        /// </summary>
        IPropertyBinding<object[], IDropdownBox> Items { get; }

        /// <summary>
        /// Optional label to display to the left of the widget.
        /// </summary>
        IPropertyBinding<string, IDropdownBox> Label { get; }

        /// <summary>
        /// Text displayed on mouse hover.
        /// </summary>
        IPropertyBinding<string, IDropdownBox> Tooltip { get; }
    }

    /// <summary>
    /// Drop-down selection field.
    /// </summary>
    internal class DropdownBox : AbstractWidget, IDropdownBox
    {
        private int selectedIndex;
        private object selectedItem;
        private object[] items;
        private string label;
        private string tooltip;

        private PropertyBinding<object, IDropdownBox> selectedItemProperty;
        private PropertyBinding<object[], IDropdownBox> itemsProperty;
        private PropertyBinding<string, IDropdownBox> labelProperty;
        private PropertyBinding<string, IDropdownBox> tooltipProperty;

        public IPropertyBinding<object, IDropdownBox> SelectedItem { get { return selectedItemProperty; } }
        public IPropertyBinding<object[], IDropdownBox> Items { get { return itemsProperty; } }
        public IPropertyBinding<string, IDropdownBox> Label { get { return labelProperty; } }
        public IPropertyBinding<string, IDropdownBox> Tooltip { get { return tooltipProperty; } }

        internal DropdownBox(ILayout parent) : base(parent)
        {
            itemsProperty = new PropertyBinding<object[], IDropdownBox>(
                this,
                value => this.items = value
            );

            selectedItemProperty = new PropertyBinding<object, IDropdownBox>(
                this,
                value =>
                {
                    selectedItem = value;
                    if (items != null)
                    {
                        selectedIndex = Array.IndexOf(items, value);
                    }
                }
            );

            labelProperty = new PropertyBinding<string, IDropdownBox>(
                this,
                value => this.label = value
            );

            tooltipProperty = new PropertyBinding<string, IDropdownBox>(
                this,
                value => this.tooltip = value
            );
        }

        public override void OnGUI()
        {
            var itemStrings = 
                items != null ? items.Select(i => i.ToString()).ToArray() : new string[] {};

            var guiContent = itemStrings.Select(m => new GUIContent(m, tooltip)).ToArray();
            var newIndex = 
                !String.IsNullOrEmpty(label)
                ? EditorGUILayout.Popup(new GUIContent(label), selectedIndex, guiContent)
                : EditorGUILayout.Popup(selectedIndex, guiContent);

            if (newIndex != selectedIndex)
            {
                selectedIndex = newIndex;
                selectedItem = items[selectedIndex];
                selectedItemProperty.UpdateView(selectedItem);
            }
        }

        public override void BindViewModel(object viewModel)
        {
            selectedItemProperty.BindViewModel(viewModel);
            itemsProperty.BindViewModel(viewModel);
            labelProperty.BindViewModel(viewModel);
            tooltipProperty.BindViewModel(viewModel);
        }
    }
}
